﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agrement;
using analy;
using System.Threading.Tasks;
using System.Net.Http;
using System.Web.Script.Serialization;

namespace SockLib.Device
{
   public  class SXGPRS : IDevice
    {
        /// <summary>
        /// 外部传进来的参数
        /// </summary>
        Dictionary<string, object> Par = new Dictionary<string, object>();
        public void SetParars(Dictionary<string, object> Params)
        {
            Par = Params;
        }

        #region 注册处理
        /// <summary>
        /// 收到数据是否满足注册条件
        /// </summary>
        /// <param name="Buffer">Socket收到的数据</param>
        /// <param name="DM">如果成功解析，DM写入相应信息</param>
        /// <returns>True：成功解析，False：未能解析（乱数据）</returns>
        public bool DeviceReg(byte[] Buffer, ref DeviceModel DM, out List<DeviceModel.SendMsg> Sendinfo)
        {
            try
            {
                Sendinfo = new List<DeviceModel.SendMsg>();
                DeviceModel DeviceModel = new DeviceModel();
                byte[] RegMsg;
                if (!RegRull(Buffer, out RegMsg))
                    return false;  //未能解析，返回失败
                byte[] id = new byte[4];   //4位UID
                Array.Copy(RegMsg, id, 4);
                id = id.Reverse().ToArray();
                DeviceModel.Uid = Converts.byteToHexStrUid(id);
                if (Convert.ToInt16(DeviceModel.Uid.Substring(0, 1)) == 1)  //第1位是1中心，其他节点
                    DeviceModel.IsCenter = true;
                else
                    DeviceModel.IsCenter = false;
                DeviceModel.DeviceGroup = DeviceModel.Uid.Substring(1, 4); //获取组号
                DeviceModel.MobileNo = ASCIIEncoding.ASCII.GetString(Buffer, 4, 11);  //获得手机号
                DM = DeviceModel;
                return true;   //返回注册成功
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 这是一个四信设备
        /// </summary>
        /// <returns></returns>
        public string DeviceType()
        {
            return "四信";
        }

        private bool RegRull(byte[] Buffer, out byte[] reg)
        {
            reg = new byte[21];
            List<byte> L = new List<byte>();
            L.AddRange(Buffer);
            while (L.Count > 20)
            {
                bool CheckError = false;
                for (int i = 0; i < 4; i++)    //UID判断
                {
                    if (L[i] > 153)
                    {
                        CheckError = true;
                        break;
                    }
                }
                for (int i = 4; i < 15; i++)  //手机号判断
                {
                    if (L[i] < 48 || L[i] > 57)
                    {
                        CheckError = true;
                        break;
                    }
                }
                if (L[20] != 0)
                    CheckError = true;
                if (CheckError == true)
                {
                    L.RemoveAt(0);   //不满足条件移除第一个元素重新开始
                    continue;
                }
                else
                {
                    Array.Copy(L.ToArray(), reg, 21);
                    return true;
                }

            }
            return false;
        }
        #endregion


        #region 获取数据转发结构
        /// <summary>
        /// 数据转发规则,数据发送给节点
        /// </summary>
        /// <param name="ReceiveData"></param>
        public bool TransferRule(byte[] ReceiveData, out List<DeviceModel.SendMsg> Sendinfo)
        {
            try
            {
                Sendinfo = new List<DeviceModel.SendMsg>();
                List<byte> rec = new List<byte>();
                rec.AddRange(ReceiveData);
                while (rec.Count > 10)
                {
                    if (rec[0] == 0x18 && rec[1] == 0x28 && rec[2] == 0x8A)
                    {
                        DeviceModel.SendMsg DS = new DeviceModel.SendMsg();
                        int deletecount = GetAgreement(rec, out DS, 0);
                        if (deletecount != 1)
                        {
                            //Sendinfo.Add(DS);                               //找不到目标就群发，注释掉找不到目标就不发
                            rec.RemoveRange(0, deletecount);
                            continue;
                        }
                        else
                        {
                            rec.RemoveAt(0);
                            continue;
                        }
                    }
                    else
                    {
                        bool GetUid = true;
                        int idlen = 0;
                        for (int i = 0; i < rec.Count - 3; i++)
                        {
                            if (rec[i] < 0x30 || rec[i] > 0x39)
                            {
                                if (rec[i] == 0x18 && rec[i + 1] == 0x28)
                                {
                                    idlen = i;
                                    break;
                                }
                                else
                                {
                                    GetUid = false;
                                    break;
                                }
                            }
                        }
                        if (!GetUid)
                        {
                            rec.RemoveAt(0);
                            continue;
                        }

                        DeviceModel.SendMsg DS = new DeviceModel.SendMsg();
                        int deletecount = GetAgreement(rec, out DS, idlen);
                        if (deletecount != 1)
                        {
                            DS.DeviceOper = Converts.DeviceOper.Transfer;
                            Sendinfo.Add(DS);                                 //发送目标匹配的
                            rec.RemoveRange(0, deletecount);
                            continue;
                        }
                        else
                        {
                            rec.RemoveAt(0);
                            continue;
                        }
                    }
                }
                if (Sendinfo.Count > 0)
                {
                    Record2API(Sendinfo);   //数据记录进API
                    return true;
                }
                else
                    return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 接收的数据往服务器发送
        /// </summary>
        /// <param name="ListRec"></param>
        private   void Record2API(List<DeviceModel.SendMsg> ListRec)
        {
            try
            {
                List<DataBaseApi. JSON_CMDModel> listcmd = new List<DataBaseApi.JSON_CMDModel>();
                foreach (DeviceModel.SendMsg item in ListRec)
                {
                    List<byte> rec = new List<byte>();
                    rec.AddRange(item.SendBuffer);
                    if (rec[0] == 0x18 && rec[1] == 0x28 && rec[2] == 0x8A)
                    {
                        DataBaseApi.JSON_CMDModel JC = new DataBaseApi.JSON_CMDModel();
                        JC.coord_cmd = rec[4].ToString();
                        JC.coord_code = rec[6] * 256 + rec[7];
                        JC.coor_type = (rec[2] - 0x80).ToString();
                        JC.gprs_code = item.TargetUid;
                        JC.network_way = "**";
                        rec[0]=0;
                        List<byte[]> returnval = new List<byte[]>();
                        Send_Agreement SA = new Send_Agreement();
                        returnval = SA.Read_CMDAgreement(rec.ToArray());
                        int pos = 2;
                        List<DataBaseApi.CMD> LC = new List<DataBaseApi.CMD>();
                        foreach (byte[] CMD in returnval)
                        {
                            DataBaseApi.CMD C = new DataBaseApi.CMD();
                            C.device_cmd = CMD[4 + pos];
                            List<int> ids = new List<int>();
                            for (int i = 6; i < CMD[5 + pos] * 2 + 6; i++)
                            {
                                int id = CMD[i + pos] * 256 + CMD[i + pos + 1];
                                ids.Add(id);
                                i++;
                            }
                            C.device_code = ids.ToArray();
                            List<byte> C_Data = new List<byte>();
                            for (int i = 6 + CMD[5 + pos] * 2; i < CMD[3 + pos] - CMD[5 + pos] * 2 - 2; i++)
                            {
                                C_Data.Add(CMD[i]);
                            }
                            C.device_data = C_Data.ToArray();
                            C.device_type = (CMD[2 + pos] >= 0x80 ? CMD[2 + pos] - 0x80 : CMD[2 + pos]);
                            C.wirless_code = CMD[0] * 256 + CMD[1];
                            LC.Add(C);
                        }
                        if (LC.Count > 0)
                        {
                            JC._list = LC.ToArray();
                            //保存到API
                            Task<DataBaseApi.Result> xx = api.AutoAdd(JC);
                        }

                    }
                    else
                        continue;
                }
            }
            catch (Exception ex)
            {
                logexception.WriteLogToFile(ex);
            }
        }

        /// <summary>
        /// 获取符合协议的转发数据,数据发送给中心
        /// </summary>
        /// <param name="rec"></param>
        /// <param name="DS"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private int  GetAgreement(List<byte > rec,out DeviceModel.SendMsg DS,int index)
        {
            DS = new DeviceModel.SendMsg();
            if (index + 3 >= rec.Count)
                return 1;
            int len = rec[index+3];
            int EndPoint = index + 3 + len + 3;
            if (EndPoint >= rec.Count)
                return 1;
            if (rec[EndPoint] == 0x58 || (4 + len + 3)>=rec.Count )
            {
                DeviceModel.SendMsg Send = new DeviceModel.SendMsg();
                if (index != 0)    //带GPRS编号单个转发，需要UID
                    Send.TargetUid = System.Text.ASCIIEncoding.ASCII.GetString(rec.ToArray(), 0, index);
                else           //不带GPRS编号群转发，UID="-1"
                    Send.TargetUid  = "-1";
                byte[] sendbyte = new byte[4 + len + 3];
                Array.Copy(rec.ToArray(), index, sendbyte, 0, 4 + len + 3);
                Send.SendBuffer = sendbyte;
                DS = Send;
               return sendbyte.Length ;
            }
            else
            {
                return 1;
            }
        }

        DataBaseApi.API api = new DataBaseApi.API();
        JavaScriptSerializer JS = new JavaScriptSerializer();
        /// <summary>
        /// 节点数据转发规则
        /// </summary>
        /// <param name="ReceiveData">收到的数据</param>
        /// <param name="uid">GPRS的编号</param>
        /// <param name="Sendinfo">需要转发的结构体</param>
        /// <returns></returns>
        public bool NodeTransferRule(byte[] ReceiveData, string uid, ref DeviceModel.SendMsg[] Sendinfos)
        {

            #region 存储数据库
            try
            {
                List<byte[]> returnval = new List<byte[]>();
                Send_Agreement SA = new Send_Agreement();
                returnval = SA.Read_Agreement(ReceiveData);
                List<DeviceModel.SendMsg> LDS = new List<DeviceModel.SendMsg>();
                foreach (byte[] res in returnval)
                {
                    Device.DeviceModel.SendMsg JSendinfo = new Device.DeviceModel.SendMsg();
                    JSendinfo.TargetUid = uid;
                    AnalyAgreeMent AAM = new AnalyAgreeMent();
                    string ARD = AAM.ReadAgreeMent(res);
                    RetCmd RC = new RetCmd();
                    RC = JS.Deserialize<RetCmd>(ARD);
                    RC.gprs_code = uid;
                    JSendinfo.SendBuffer = System.Text.Encoding.Default.GetBytes(JS.Serialize(RC));
                    LDS.Add(JSendinfo);
                    DataBaseApi.ControlHistory CH = new DataBaseApi.ControlHistory()
                    {
                        GPRSNumber = uid,
                        Number = RC.device_code,
                        Operate = RC.device_cmd,
                        OperateTime = DateTime.Now,
                        ReadOrWrite = false,
                        Describe = RC.explain
                    };
                    Task<bool> xx = api.SaveHistory(CH);
                }
            }
            catch (Exception ex)
            {
                logexception.WriteLogToFile(ex);
            } 
            #endregion

            Device.DeviceModel.SendMsg Sendinfo = new Device.DeviceModel.SendMsg();
            Sendinfo.TargetUid = uid;
            Sendinfo.SendBuffer = ReceiveData;
            Sendinfos = new Device.DeviceModel.SendMsg[1];
            Sendinfos[0] = Sendinfo;
            return true;
        }
        #endregion


        #region 数据转换

        /// <summary>
        /// 心跳包格式
        /// </summary>
        /// <param name="TargetUid">发给的中心模块ID</param>
        /// <param name="uid">在线中心模块ID集合</param>
        /// <returns></returns>
        public List<byte[]> HeartBeatConvert(string TargetUid, string[] uid)
        {

            string senduid = "";
            List<string> LS = new List<string>();
            List<byte[]> LB = new List<byte[]>();
            LS.AddRange(uid);
            int PackNum = 20;
            List<byte> SendBuffer = new List<byte>();
            while (LS.Count > 0)
            {
                senduid = "";
                if (LS.Count / PackNum > 0)
                {
                    for (int i = 0; i < PackNum; i++)
                        senduid += LS[i] + "#";
                    LS.RemoveRange(0, PackNum);
                }
                else
                {
                    for (int i = 0; i < LS.Count % PackNum; i++)
                        senduid += LS[i] + "#";
                    LS.RemoveRange(0, LS.Count % PackNum);
                }
                byte PackType = 1;
                if (LB.Count != 0 || SendBuffer.Count != 0)
                    PackType = 2;
                Agrement.Send_Agreement AgreMent = new Agrement.Send_Agreement();
                byte[] byteArray = System.Text.Encoding.Default.GetBytes(senduid);
                byte[] DeviceSend = AgreMent.Make_AgreementNode(0x0b, PackType, new int[] { 0 }, byteArray);
                if (SendBuffer.Count + DeviceSend.Length < 1024*1024)
                    SendBuffer.AddRange(DeviceSend);
                else
                {
                    LB.Add(SendBuffer.ToArray());
                    SendBuffer.Clear();
                    SendBuffer.AddRange(DeviceSend);

                }
            }
            if (SendBuffer.Count > 0)
                LB.Add(SendBuffer.ToArray());
            return LB;
        }

        /// <summary>
        /// 发送数据转换
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] SendDataConvert(byte[] Data)
        {
            SXDataConvert.SXDataConvent SXConvert = new SXDataConvert.SXDataConvent();
            return SXConvert.Byte2Send(Data);
        }

        /// <summary>
        /// 接收数据转换
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] ReceiveDataConvert(byte[] Data)
        {
            SXDataConvert.SXDataConvent SXConvert = new SXDataConvert.SXDataConvent();
            return SXConvert.Rec2Byte(Data);
        }

        public byte[] DataPacket(DeviceModel.SendMsg SendMsg)
        {
            return SendMsg.SendBuffer ;
        }
        #endregion



        #region 心跳包处理
        /// <summary>
        /// 心跳包不做任何转发处理
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
       public  bool IsHeartPack(byte[] Pack)
        {
            if (Pack.Length == 1 && (Pack[0] == 0x2B || Pack[0] == 0xfe))
                return true;
            return false;

        }
        #endregion

        #region 显示LOG区发送数据
        public string SendString(string uid, byte[] msg)
        {
            //if (uid.Substring(0, 1) == "1")
            //    return System.Text.Encoding.Default.GetString(msg);
            //else
                return Converts.byteToHexStr(msg);
        }
        #endregion 
    }
}
